package com.nifostasky.main.reflex.menthodfield;

/**
 * 反射获取属性
 */

/**
 * class 获取 Field对象的方法
 * | 返回值    | 方法说明                                                     |
 * | :-------- | :----------------------------------------------------------- |
 * | `Field`   | `getField(String name)` 返回一个 `Field` 对象，它反映此 `Class` 对象所表示的类的public属性。（可以获取父类的方法） |
 * | `Field[]` | `getFields()` 返回所有`Field`属性，它反映此 `Class` 对象所表示的类的public属性。（可以获取父类的方法） |
 * | `Field`   | `getDeclaredField(String name)` 返回一个 `Field` 对象，该对象反映此 `Class` 对象所表示的类的public/private属性。（只获取当前类的方法） |
 * | `Field[]` | `getDeclaredFields()` 返回所有`Field`属性，该对象反映此 `Class` 对象所表示的类的public/private属性。（只获取当前类的方法） |
 */

import lombok.SneakyThrows;

import java.lang.reflect.Field;

/**
 * Field类中方法
 * | 返回值                    | 方法说明                                                     |
 * | :------------------------ | :----------------------------------------------------------- |
 * | `Object`                  | `get(Object obj)` 返回指定对象上此 `Field` 表示的字段的值。  |
 * | `<T extends Annotation>T` | `getAnnotation(Class<T> annotationClass)` 如果存在该元素的指定类型的注解，则返回这些注释，否则返回 null。 |
 * | `boolean`                 | `getBoolean(Object obj)` 获取一个静态或实例 `boolean` 字段的值。 |
 * | `byte`                    | `getByte(Object obj)` 获取一个静态或实例 `byte` 字段的值。   |
 * | `char`                    | `getChar(Object obj)` 获取 `char` 类型或另一个通过扩展转换可以转换为 `char` 类型的基本类型的静态或实例字段的值。 |
 * | `Annotation[]`            | `getDeclaredAnnotations()` 返回直接存在于此元素上的所有注解。 |
 * | `Class<?>`                | `getDeclaringClass()` 返回表示类或接口的 `Class` 对象，该类或接口声明由此 `Field` 对象表示的字段。 |
 * | `double`                  | `getDouble(Object obj)` 获取 `double` 类型或另一个通过扩展转换可以转换为 `double` 类型的基本类型的静态或实例字段的值。 |
 * | `float`                   | `getFloat(Object obj)` 获取 `float` 类型或另一个通过扩展转换可以转换为 `float` 类型的基本类型的静态或实例字段的值。 |
 * | `Type`                    | `getGenericType()` 返回一个 `Type` 对象，它表示此 `Field` 对象所表示字段的声明类型。 |
 * | `int`                     | `getInt(Object obj)` 获取 `int` 类型或另一个通过扩展转换可以转换为 `int` 类型的基本类型的静态或实例字段的值。 |
 * | `long`                    | `getLong(Object obj)` 获取 `long` 类型或另一个通过扩展转换可以转换为 `long` 类型的基本类型的静态或实例字段的值。 |
 * | `int`                     | `getModifiers()` 以整数形式返回由此 `Field` 对象表示的字段的 Java 语言修饰符。 |
 * | `String`                  | `getName()` 返回此 `Field` 对象表示的字段的名称。            |
 * | `short`                   | `getShort(Object obj)`获取 `short` 类型或另一个通过扩展转换可以转换为 `short` 类型的基本类型的静态或实例字段的值。 |
 * | `Class<?>`                | `getType()` 返回一个 `Class` 对象，它标识了此 `Field` 对象所表示字段的声明类型。 |
 * | `boolean`                 | `isEnumConstant()` 如果此字段表示枚举类型的元素，则返回 `true`；否则返回 `false`。 |
 * | `void`                    | `set(Object obj, Object value)` 将指定对象变量上此 `Field` 对象表示的字段设置为指定的新值。 |
 * | `void`                    | `setBoolean(Object obj, boolean z)` 将字段的值设置为指定对象上的一个 `boolean` 值。 |
 * | `void`                    | `setByte(Object obj, byte b)` 将字段的值设置为指定对象上的一个 `byte` 值。 |
 * | `void`                    | `setChar(Object obj, char c)` 将字段的值设置为指定对象上的一个 `char` 值。 |
 * | `void`                    | `setDouble(Object obj, double d)` 将字段的值设置为指定对象上的一个 `double` 值。 |
 * | `void`                    | `setFloat(Object obj, float f)` 将字段的值设置为指定对象上的一个 `float` 值。 |
 * | `void`                    | `setInt(Object obj, int i)` 将字段的值设置为指定对象上的一个 `int` 值。 |
 * | `void`                    | `setLong(Object obj, long l)` 将字段的值设置为指定对象上的一个 `long` 值。 |
 * | `void`                    | `setShort(Object obj, short s)` 将字段的值设置为指定对象上的一个 `short` 值。 |
 * | `String`                  | `toGenericString()` 返回一个描述此 `Field`（包括其一般类型）的字符串。 |
 * | `void`                    | `setAccessible(boolean flag)` 将此对象的 accessible 标志设置为指示的布尔值,即设置其可访问性。 |
 */
public class FieldClass {
    @SneakyThrows
    public static void fieldTest(){
        //获取实例
        String classpath = "com.nifostasky.main.reflex.template.Student";
        Class<?> aClass = Class.forName(classpath);
        Object object = aClass.newInstance();
        //设置并获取属性值
        Field nameField = aClass.getDeclaredField("name");
        //设置private属性可访问
        nameField.setAccessible(true);
        nameField.set(object,"张三");
        Object name = nameField.get(object);
        System.out.println(name);
        System.out.println(nameField.getDeclaringClass());
        System.out.println(nameField.getType());
    }

    public static void main(String[] args) {
        FieldClass.fieldTest();
    }
}
